home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / fdimg / —‹Œêsrc.lzh / meta.c < prev    next >
C/C++ Source or Header  |  1993-01-13  |  22KB  |  1,151 lines

  1. #include    "3DDEF.H"
  2. #include    "GLOBAL.H"
  3. #include    "FORWARD.H"
  4. #include    "XCODE.H"
  5.  
  6. extern COMMAND_UNIT command_table[MAX_COMMAND_NUMBER];
  7. extern UBYTE search_w1[VERY_LONG_LINE * 40];
  8.  
  9. /* マークへのジャンプ */
  10. void
  11. meta_ctrl_g()
  12. {
  13.     UNIT *wp;
  14.     int bp;
  15.     int y;
  16.     int a;
  17.  
  18.     if ((a = etc_get_arg()) >= MAX_MARK) {
  19.         under_print((STR)"マーク番号が不適当です");
  20.         return;
  21.     }
  22.  
  23.     line_seigyou();
  24.     if (wp = mark_get_mark(a,&bp)) {
  25.         CL = wp;
  26.         line_cl_cl();
  27.         if ((y = window_is_this_line_in_current(CL)) < 0) {    /* 入ってない */
  28.             disp_cl_center();
  29.         } else {
  30.             CY = y;
  31.         }
  32.         work_line_analyze();
  33.         CPX = work_byte_to_CPX(bp);
  34.         CX0 = CX = ANALYZE[CPX].XPOS;
  35.         under_blanc();
  36.         work_cursor_cpx();
  37.     } else {
  38.         UBYTE w[MAXLINE];
  39.         sprintf((char *) w,"マーク %1d は設定されていません",a);
  40.         under_print(w);
  41.     }
  42. }
  43.     
  44. /* 左1ワード削除 */
  45. void
  46. meta_ctrl_h()
  47. {
  48.     meta_d_sub(meta_b);
  49. }
  50.  
  51. /* ウインドウの書き直し */
  52. void
  53. meta_ctrl_l()
  54. {
  55.     int a;
  56.  
  57.     line_seigyou();
  58.     a = etc_get_arg();
  59.     if (!a) {
  60.         disp_cl_center();
  61.     } else if ((a-1) > (CWY1-CWY0)) {
  62.         disp_cl_y(CWY1);
  63.     } else {
  64.         disp_cl_y(a-1);
  65.     }
  66.     work_cursor_cpx();
  67. }
  68.  
  69. /* 確認置換 */
  70. void
  71. meta_ctrl_r()
  72. {
  73.     meta_replace(0);
  74. }
  75.  
  76. void
  77. meta_replace(int go_flag)
  78. {
  79.     UBYTE w[VERY_LONG_LINE * 4];
  80.     UNIT *pp0,*pp,*p1,*p2;
  81.     UNIT *lp1,*lp2;
  82.     int bb0,bb,b1,b2;
  83.     int count = 0;
  84.     UINT c;
  85.     int xflag,flag,uflag;
  86.     int give_up;
  87.  
  88.     lp1 = NULL;    /* 初期化 */
  89. /* go_flag = 確認せずに置換を強行 */
  90. /* xflag = 置換を続行 */
  91. /* flag = 次の置換に行ってはいけない */
  92.  
  93.     etc_string_esc_cnv(STRING_ESC1,STRING_ESC1_s);
  94.     if (go_flag) {
  95.         sprintf((char *) w,"置換 [%s]<META>",STRING_ESC1_s);
  96.     } else {
  97.         sprintf((char *) w,"確認置換 [%s]<META>",STRING_ESC1_s);
  98.     }
  99.     if (under_input_esc(w,STRING_ESC1) < 0) {    /* 無効であった = ^G */
  100.         under_print((STR)"[中断]");
  101.         return;
  102.     }
  103.     if (!*STRING_ESC1) {    /* 置換元が無い */
  104.         under_blanc();
  105.         return;
  106.     }
  107.     etc_string_esc_cnv(STRING_ESC1,STRING_ESC1_s);
  108.  
  109.     etc_string_esc_cnv(STRING_ESC2,STRING_ESC2_s);
  110.     sprintf((char *) w,"with [%s]<META>",STRING_ESC2_s);
  111.     if (under_input_esc(w,STRING_ESC2) < 0) {    /* 無効であった = ^G */
  112.         under_print((STR)"[中断]");
  113.         return;
  114.     }
  115.     etc_string_esc_cnv(STRING_ESC2,STRING_ESC2_s);
  116.     /* 確認置換実行 */
  117.     line_seigyou();    /* 整行する */
  118.     pp0 = pp = CL;
  119.     bb0 = bb = ANALYZE[CPX].BPOS;
  120.     xflag = 1;
  121.     uflag = 0;
  122.     strcpy(STRING_ESC1_u,STRING_ESC1);
  123.     etc_jstrup(STRING_ESC1_u);
  124.     while(xflag) {
  125.         if (!uflag) {
  126.             give_up = ctrl_s_get_string(pp,bb,STRING_ESC1_u,&p1,&b1,&p2,&b2);
  127.             if (!give_up) {
  128.                 break;
  129.             }
  130.         } else {    /* ??? */
  131.             uflag = 0;
  132.             give_up = ctrl_s_get_string(pp,bb,STRING_ESC1_u,&p1,&b1,&p2,&b2);
  133.             if (!give_up) {
  134.                 break;
  135.             }
  136.         }
  137.         if (give_up < 0) {    /* 中断だ */
  138.             goto replace_stop;
  139.         }
  140.         jump(p1,b1);
  141. /* 置換元に属性が前置している可能性がある */
  142.         b1 = line_remove_attribute(b1);
  143. /* 前置している属性までさかのぼる */
  144.  
  145.         if (!go_flag) {    /* 確認モードである */
  146.             sprintf((char *)w,"置換 '%s' with '%s'?",STRING_ESC1_s,STRING_ESC2_s);
  147.             under_print(w);
  148.         }
  149.         if (CPX && (line_cl_1byte(CPX-1) == CR)) {
  150.                 /* 左が改行 */
  151.             if (CL->ATO == TAIL) {
  152.                 ctrl_b();
  153.             } else {
  154.                 ctrl_f();
  155.             }
  156.         }
  157.         work_cursor_cpx();
  158.         flag = 1;
  159.         while(flag) {
  160.             int lb1,lb2;
  161.             UBYTE code;
  162.  
  163.             if (((code = fep_get_key()) == '['-'@') || (code == 'G'-'@')) {
  164.                 etc_beep();
  165.                 goto replace_stop;
  166.             }
  167.             if (go_flag) {
  168.                 c = 'Y';    /* ううう、CL は最後にいじるだけにすべき! */
  169.             } else {
  170.                 c = toupper(fep_inkey_raw());
  171.             }
  172.             switch(c) {
  173.             case '!':    /* 最後まで強行 */
  174.                 go_flag = 1;
  175.             case 'Y':
  176.             case ' ':
  177.                 line_seigyou();/* ,,, */
  178.                 work_replace_str_echo_xxx(p1,b1,p2,b2,STRING_ESC2);
  179.                 lp1 = p1;
  180.                 lb1 = b1;
  181.                 line_seigyou();
  182.                     /* BAG が発生する可能性有り */
  183.                 ctrl_s_trace_real_byte(p1,b1,strlen(STRING_ESC2),&pp,&bb);
  184. /*printf("[%x:%d,%x:%d]",p1,b1,pp,bb);binkey();*/
  185.                 lp2 = pp;
  186.                 lb2 = bb;
  187.                 jump(pp,bb);
  188.                 count++;
  189.                 flag = 0;
  190.                 change_check();
  191.                 break;
  192.  
  193.             case 'N':
  194.                 pp = p2;
  195.                 bb = b2;
  196.                 flag = 0;
  197.                 break;
  198.             case 'U':    /* 1個だけチャイして続行 */
  199.                 if (lp1) {
  200.                     work_replace_str_echo_xxx(lp1,lb1,lp2,lb2,STRING_ESC1);
  201.                     line_seigyou();
  202.                         /* BAG が発生する可能性有り */
  203.                     count--;
  204.                     change_check();
  205.                     pp = lp1;
  206.                     bb = lb1;
  207.                     lp1 = NULL;
  208.                     flag = 0;
  209.                     uflag = 1;
  210.                 } else {
  211.                     etc_beep();
  212.                     work_cursor_cpx();
  213.                 }
  214.                 break;
  215.             case '.':
  216.                 pp = pp0;
  217.                 bb = bb0;
  218.                 flag = 0;
  219.                 xflag = 0;
  220.                 break;
  221. /*                jump(pp0,bb0);*/
  222.             case 'G'-'@':    /* その場で中断 */
  223.             case '['-'@':
  224. replace_stop:
  225.                 flag = 0;
  226.                 xflag = 0;
  227.                 pp = CL;
  228.                 bb = ANALYZE[CPX].BPOS;
  229.                 break;
  230.             default:    /* beep 音を出してヘルプ */
  231.                 etc_beep();
  232.             case '?':    /* ヘルプ */
  233. under_print((STR)"(Y or SPACE)置換 (N)無視 (!)強行 (U)キャンセル (^G)中断 (.)戻る (?)ヘルプ:");
  234.                 continue;
  235.             }
  236.         }
  237.     }
  238.     jump(pp,bb);
  239.     if (CPX && (line_cl_1byte(CPX-1) == CR)) {
  240.             /* 左が改行 */
  241.         ctrl_b();
  242.     }
  243.     sprintf((char *)w,"%d 箇所 置換しました",count);
  244.     under_print(w);
  245. }
  246.  
  247. void
  248. jump(UNIT *p1,int b1)
  249. {
  250.     int y;
  251.  
  252.     CL = p1;
  253.     line_cl_cl();
  254.     if ((y = window_is_this_line_in_current(CL)) < 0) {    /* 入ってない */
  255.         disp_cl_center();
  256.     } else {
  257.         CY = y;
  258.     }
  259.     work_line_analyze();
  260.     CPX = work_byte_to_CPX(b1);
  261.     CX0 = CX = ANALYZE[CPX].XPOS;
  262. }
  263.  
  264. /* 次ウインドウ次頁 */
  265. void
  266. meta_ctrl_v()
  267. {
  268.     ctrl_x_o();    /* 次ページへ */
  269.     ctrl_v();
  270.     ctrl_x_p();    /* 戻る */
  271. }
  272.  
  273. /* 次ウインドウ前頁 */
  274. void
  275. meta_ctrl_z()
  276. {
  277.     ctrl_x_o();    /* 次ページへ */
  278.     ctrl_z();
  279.     ctrl_x_p();    /* 戻る */
  280. }
  281.  
  282. /* マークセット */
  283. void
  284. meta_space()
  285. {
  286.     int a;
  287.  
  288.     if ((a = etc_get_arg()) <= MAX_MARK) {
  289.         UBYTE w[MAXLINE];
  290.         mark_set_mark(a);
  291.         sprintf((char *) w,"[マーク %1d 設定]",a);
  292.         under_print(w);
  293.     } else {
  294.         under_print((STR)"マーク番号が不適当です");
  295.     }
  296. }
  297.  
  298. void
  299. meta_arg0()
  300. {
  301.     meta_argn(0);
  302. }
  303.  
  304. void
  305. meta_arg1()
  306. {
  307.     meta_argn(1);
  308. }
  309.  
  310. void
  311. meta_arg2()
  312. {
  313.     meta_argn(2);
  314. }
  315.  
  316. void
  317. meta_arg3()
  318. {
  319.     meta_argn(3);
  320. }
  321.  
  322. void
  323. meta_arg4()
  324. {
  325.     meta_argn(4);
  326. }
  327.  
  328. void
  329. meta_arg5()
  330. {
  331.     meta_argn(5);
  332. }
  333.  
  334. void
  335. meta_arg6()
  336. {
  337.     meta_argn(6);
  338. }
  339.  
  340. void
  341. meta_arg7()
  342. {
  343.     meta_argn(7);
  344. }
  345.  
  346. void
  347. meta_arg8()
  348. {
  349.     meta_argn(8);
  350. }
  351.  
  352. void
  353. meta_arg9()
  354. {
  355.     meta_argn(9);
  356. }
  357.  
  358. void
  359. meta_argn(int b)
  360. {
  361.     UINT k;
  362.     int w = 0,w0;
  363.  
  364.     etc_set_arg(b);
  365.     disp_cursor_on();    /* カーソルを出す */
  366.     disp_show_cursor();    /* カーソルのブリンクを強制的にオンにする */
  367.     fep_key_clear();    /* キーバッファのクリア */
  368.     k = fep_inkey_raw();
  369.     while(('0' <= k) && (k <= '9')) {    /* 数字であり続ける限り */
  370.         w0 = w;
  371.         etc_set_arg(w = etc_get_arg() *10 +(k - '0'));
  372.         if ((w/10) < w0) {
  373.             w = 0;
  374.             etc_set_arg(0);
  375.             k = (UINT) '0';
  376.         } else {
  377.             k = fep_inkey_raw();
  378.         }
  379.     }
  380.     fep_push_key(k);    /* 戻す */
  381. }
  382.  
  383. #if 0
  384. typedef struct COMMAND_UNIT {
  385.     UBYTE    COMMAND_STRING[MAX_COMMAND_STROKE+1];        /* */
  386.     UINT    COMMAND_FLAG;                    /* 実行後の処理のフラグ */
  387.     void    (*FUNCTION)();                    /* */
  388.     UBYTE    COMMAND_NAME[MAX_COMMAND_NAME_LENGTH+1];    /* */
  389. } COMMAND_UNIT;
  390. #endif
  391.  
  392. /* キーバインド一覧 */
  393. void
  394. meta_a()
  395. {
  396.     int i,n;
  397.     UWORD *s;
  398.     UWORD c;
  399.     int f,t,wn;
  400.     UBYTE filename[MAXLINE];
  401.     UBYTE w[MAXLINE];
  402.     UBYTE wlist[MAX_WINDOW];    /* フラグ用 */
  403.     UNIT *p;
  404.  
  405.     line_seigyou();
  406.     if ((f = file_search((STR)"[KeyDEF]")) >= 0) {    /* 既にある */
  407.         UBYTE list[MAX_WINDOW];
  408.  
  409.         t = etc_text_search(f);
  410. /* list の中にフラグをセットして返す */
  411. /* 指定のテキスト番号を扱っているウインドウ番号を返す */
  412.         if (window_which_has_text_number(t,list)) {
  413.                 /* ウインドウが存在する */
  414.             for(i=0;i<MAX_WINDOW;i++) {
  415.                 if (list[i]) {    /* 最初のウインドウで抜ける */
  416.                     window_change(i);
  417.                     break;
  418.                 }
  419.             }
  420.         } else {    /* ウインドウが存在しない */
  421.             if ((wn = ctrl_x_20()) < 0) {    /* 新しく作られたウインドウ */
  422.                 /* できなかった */
  423.                 return;
  424.             }
  425.             window_change(wn);
  426.             ctrl_x_ctrl_f1_alway((STR)"[KeyDEF]");
  427.         }
  428.     } else {
  429.         if (window_get_free_text_number() < 0) {    /* 開いたテキストがない */
  430.             etc_inp_y((STR)"扱うテキストの数が多すぎます。中断します [Y]?");
  431.             return;
  432.         }
  433.         if ((wn = ctrl_x_20()) < 0) {    /* 新しく作られたウインドウ */
  434.             /* できなかった */
  435.             return;
  436.         }
  437.         window_change(wn);    /* カレントを移動する */
  438.     }
  439.     /* wn にバッファリストを表示する */
  440.     if (strcmp(FILE_NAMES_ST[WDATA[CWN].WTEXTS].CONTENT,"[KeyDEF]")) {
  441.         ctrl_x_ctrl_f0((STR)"[KeyDEF]");
  442.     } else if (HEAD->ATO != TAIL) {
  443.         line_deleten_echo(HEAD,TAIL);
  444.         buff_read_file_new();
  445.     }
  446.     ctrl_x_f0(COLUMN_MAX);
  447.     CL= HEAD->ATO;
  448.     line_store_and_echo(CL,(STR)"キー定義\n");
  449.     line_cl_cl();
  450.     CX = CX0 = CPX = 0;
  451.  
  452.     for(n = 0;n < MAX_COMMAND_NUMBER;n++) {
  453.         s = command_table[n].COMMAND_STRING;    /* ストローク */
  454.         if (!*s) {    /* 割り当てがない */
  455.             continue;
  456.         }
  457.         i = 0;
  458.         while(c = *s++) {
  459.             if (i) {
  460.                 w[i++] = '-';
  461.             }
  462.             if (c < 0x20) {
  463.                 if (c == '\x1b') {
  464.                     meta_a_sub(w,&i,"ESC");
  465.                 } else if (c == 'M' - '@') {
  466.                     meta_a_sub(w,&i,"<NL>");
  467.                 } else {
  468.                     w[i++] = '^';
  469.                     w[i++] = c + '@';
  470.                 }
  471.             } else if (c > 0x100) {    /* XF など */
  472.                 switch(c) {
  473.                 case FEP_HELP_CODE:
  474.                     meta_a_sub(w,&i,"HELP");
  475.                     break;
  476.                 case (FEP_HELP_CODE | 0x20):
  477.                     meta_a_sub(w,&i,"CTRL+HELP");
  478.                     break;
  479.                 case FEP_DEL_CODE:
  480.                     meta_a_sub(w,&i,"DEL");
  481.                     break;
  482.                 case FEP_HOME_CODE:
  483.                     meta_a_sub(w,&i,"HOME");
  484.                     break;
  485.                 case FEP_CLR_CODE:
  486.                     meta_a_sub(w,&i,"CLR");
  487.                     break;
  488.                 case FEP_UNDO_CODE:
  489.                     meta_a_sub(w,&i,"UNDO");
  490.                     break;
  491.                 case FEP_ROLLDN_CODE:
  492.                     meta_a_sub(w,&i,"ROLL UP");
  493.                     break;
  494.                 case FEP_ROLLUP_CODE:
  495.                     meta_a_sub(w,&i,"ROLL DOWN");
  496.                     break;
  497.                 defailt:
  498.                     break;
  499.                 }
  500.                 break;
  501.             } else {
  502.                 if (c == ' ') {
  503.                     meta_a_sub(w,&i,"<SP>");
  504.                 } else {
  505.                     w[i++] = c;
  506.                 }
  507.             }
  508.         }
  509.         if (i) {
  510.             do {
  511.                 w[i++] = ' ';
  512.             } while(i < 16);    /* 適当 */
  513.  
  514.             strcpy(&w[i],command_table[n].COMMAND_NAME);
  515.             strcat(w,"\n");
  516.             p = line_get_free_and_store_ck(w);
  517.             line_append1_echo(p);
  518.         }
  519.     }
  520.     ctrl_l();
  521. }
  522.  
  523. void
  524. meta_a_sub(STR w,int *i,STR s)
  525. {
  526.     register int l;
  527.  
  528.     l = strlen(s);
  529.     strncpy(&w[*i],s,l);
  530.     (*i) += l;
  531. }
  532.  
  533.  
  534. /* @@@@@@AAAAAABBBBBBBCCCCCC */
  535. /*      ^      ^
  536. /*            ^ ^
  537. /* 1ワード左へ */
  538. void
  539. meta_b()
  540. {
  541.     if (meta_b_sub() >= 0) {    /* 前のワードを1つ追い越している */
  542.         ctrl_f();        /* 戻す */
  543.     }
  544.     if (!etc_group(line_cpx_code())) {    /* おっと、記号だぜ */
  545.         if (meta_b_sub() >= 0) {    /* 前のワードを1つ追い越している */
  546.             ctrl_f();        /* 戻す */
  547.         }
  548.     }
  549. }
  550.  
  551. /* 1ワード右へ */
  552. void
  553. meta_f()
  554. {
  555.     int g;
  556.  
  557.     if ((g = meta_f_sub()) >= 0) {    /* 終端ではない */
  558.         if (!g) {        /* おっと、記号だぜ */
  559.             meta_f_sub();
  560.         }
  561.     }
  562. }
  563.  
  564. /* アルファベットを通り過ぎるまで行く */
  565. void
  566. meta_f_alpha_end()
  567. {
  568.     register UINT c;
  569.     register int g,g0,flag;
  570.  
  571.     g0 = etc_group(line_cpx_code());
  572.     flag = (g0 == 1);
  573.     while(1) {
  574.         if ((((c = line_cpx_code()) == EOS) || (c == CR)) && (CL->ATO == TAIL)) {
  575.             return;        /* 終端である */
  576.         }
  577.         ctrl_f();
  578.         if (!(c = line_cpx_code())) {    /* 行末である */
  579.             ctrl_f();
  580.             c = line_cpx_code();
  581.         }
  582.         if ((g = etc_group(c)) == 1) {
  583.             g0 = flag = 1;
  584.             continue;
  585.         } else if ((g0 > 0) && (!g)) {
  586.             return;
  587.         } else {
  588.             g0 = g;
  589.         }
  590.         if (flag) {
  591.             return;
  592.         }
  593.     }
  594. }
  595.  
  596. int
  597. meta_f_sub()
  598. {
  599.     UINT c;
  600.     int g,g0;
  601.  
  602.     g0 = etc_group(line_cpx_code());
  603.     while(1) {
  604.         if ((((c = line_cpx_code()) == EOS) || (c == CR)) && (CL->ATO == TAIL)) {
  605.             return(-1);    /* 終端である */
  606.         }
  607.         ctrl_f();
  608.         if (!(c = line_cpx_code())) {    /* 行末である */
  609.             ctrl_f();
  610.             c = line_cpx_code();
  611.         }
  612.         g = etc_group(c);
  613.         if (g != g0) {
  614.             return(g);
  615.         }
  616.     }
  617. }
  618.  
  619. int
  620. meta_b_sub()
  621. {
  622.     UINT c;
  623.     int count = 0;
  624.     int g,g0;
  625.  
  626.     g0 = etc_group(line_cpx_code());
  627.     while(1) {
  628.         if (!CPX && (CL == HEAD->ATO)) {
  629.             return(-1);    /* 先頭である */
  630.         }
  631.         ctrl_b();
  632.         if (!(c = line_cpx_code())) {
  633.             ctrl_b();
  634.             c = line_cpx_code();
  635.         }
  636.         g = etc_group(c);
  637.         if (g != g0) {
  638.             if (count) {
  639.                 return(g);
  640.             } else {
  641.                 g0 = g;
  642.             }
  643.         }
  644.         count++;
  645.     }
  646. }
  647.  
  648. int
  649. meta_b_sub_ed()
  650. {
  651.     UINT c;
  652.     int count = 0;
  653.     int g,g0;
  654.  
  655.     g0 = etc_group(line_cpx_code());
  656.     while(1) {
  657.         if (!CPX && (CL == HEAD->ATO)) {
  658.             return(-1);    /* 先頭である */
  659.         }
  660.         ctrl_b();
  661.         if (!(c = line_cpx_code())) {
  662.             ctrl_b();
  663.             c = line_cpx_code();
  664.         }
  665.         if (c == CR) {
  666.             return(-1);
  667.         }
  668.         g = etc_group(c);
  669.         if (g != g0) {
  670.             if (count) {
  671.                 return(g);
  672.             } else {
  673.                 g0 = g;
  674.             }
  675.         }
  676.         count++;
  677.     }
  678. }
  679.  
  680. /* 次の一語を削除 */
  681. /* ^W の変形だな */
  682. void
  683. meta_d()
  684. {
  685.     meta_d_sub(meta_f);
  686. }
  687.  
  688. /* 現在位置と、function を実行したあとで削除を実行する */
  689. void
  690. meta_d_sub(void (*function)())
  691. {
  692.     UNIT *wp;
  693.     int bp,a;
  694.  
  695.  
  696.     if (commander_is_last_cut_buff_type()) {
  697.     } else {    /* でなければ、カットバッファをクリア */
  698.         buff_clear_cut_buff();
  699.     }
  700.  
  701.     line_seigyou();
  702.     mark_set_mark(a = XCODE_SYSMARK - XCODE_MARK + CWN);    /* 現在位置にマークする */
  703.     (*function)();
  704.     wp = mark_get_mark(a,&bp);    /* マークを得る */
  705.     if ((wp != CL) || (bp != ANALYZE[CPX].BPOS)) {    /* 移動した */
  706.         change_check();
  707.         work_delete_to_cut_buff(CL,ANALYZE[CPX].BPOS,wp,bp);
  708.         mark_erase_mark(XCODE_SYSMARK - XCODE_MARK + CWN);    /* システムマークを消す */
  709.         work_cursor_cpx();
  710.     }
  711. }
  712.  
  713. /* 指定行へジャンプ */
  714. void
  715. meta_g()
  716. {
  717.     int a;
  718.  
  719.     if (!(a = etc_get_arg())) {    /* 行番号の事前指定が無かった */
  720.                     /* 行番号を入力する */
  721.         UBYTE w[MAXLINE];
  722.  
  723.         under_input_cr_raw((STR)"行番号: ",w);
  724.         a = atoi((char *)w);
  725.     }
  726.     meta_g0(a);
  727. }
  728.  
  729. /* 指定行へジャンプ */
  730. void
  731. meta_g0(int a)
  732. {
  733.     if (a > 0) {    /* ジャンプ */
  734.         int y;
  735.         register int lc=0;
  736.         register UNIT *p;
  737.  
  738.         line_seigyou();
  739.         p = HEAD->ATO;
  740.         while(p != TAIL) {
  741.             if (++lc == a) {
  742.                 CL = p;
  743.                 break;
  744.             }
  745.             p = p->ATO;
  746.         }
  747.         if (p == TAIL) {
  748.             CL = TAIL->MAE;
  749.         }
  750.         line_cl_cl();
  751.         if ((y = window_is_this_line_in_current(CL)) < 0) {    /* 入ってない */
  752.             disp_cl_center();
  753.         } else {
  754.             CY = y;
  755.         }
  756.         work_line_analyze();
  757.         CPX = CX0 = CX = 0;
  758.         under_blanc();
  759.         work_cursor_cpx();
  760.     }
  761. }
  762.  
  763. /* 無条件置換 */
  764. void
  765. meta_r()
  766. {
  767.     meta_replace(1);
  768. }
  769.  
  770. /* 指定範囲をバッファに取り込む */
  771. void
  772. meta_w()
  773. {
  774.     UNIT *wp;
  775.     int bp;
  776.     int y;
  777.     int a;
  778.  
  779.     if (commander_is_last_cut_buff_type()) {
  780.     } else {    /* でなければ、カットバッファをクリア */
  781.         buff_clear_cut_buff();
  782.     }
  783.  
  784.     if ((a = etc_get_arg()) >= MAX_MARK) {
  785.         under_print((STR)"マーク番号が不適当です");
  786.         return;
  787.     }
  788.  
  789.     line_seigyou();
  790.     if (wp = mark_get_mark(a,&bp)) {
  791.         work_copy_to_cut_buff(wp,bp,CL,ANALYZE[CPX].BPOS);
  792.         under_print((STR)"[コピー]");
  793.         work_cursor_cpx();
  794.     } else {
  795.         UBYTE w[MAXLINE];
  796.         sprintf((char *) w,"マーク %1d は設定されていません",a);
  797.         under_print(w);
  798.     }
  799. }
  800.  
  801. void
  802. meta_left_blaket()
  803. {
  804.     int y;
  805.  
  806.     CL = HEAD->ATO;
  807.     line_cl_cl();
  808.     if ((y = window_is_this_line_in_current(CL)) < 0) {    /* 入ってない */
  809.         line_seigyou();
  810.         disp_cl_center();
  811.     } else {
  812.         CY = y;
  813.     }
  814.     work_line_analyze();
  815.     CX0 = CPX = 0;
  816.     under_blanc();
  817.     work_cursor_cpx();
  818. }
  819.  
  820. void
  821. meta_right_blaket()
  822. {
  823.     int y;
  824.  
  825.     CL = TAIL->MAE;
  826.     line_cl_cl();
  827.     if ((y = window_is_this_line_in_current(CL)) < 0) {    /* 入ってない */
  828.         line_seigyou();
  829.         disp_cl_center();
  830.     } else {
  831.         CY = y;
  832.     }
  833.     work_line_analyze();
  834.     ctrl_e();
  835.     under_blanc();
  836.     work_cursor_cpx();
  837. }
  838.  
  839. void
  840. meta_upper_bar()
  841. {
  842.     if (CURRENT_CHANGED) {
  843.         CURRENT_CHANGED = 0;
  844.         disp_btm_changed_erase_x(CURRENT_TEXT);
  845.     } else {
  846.         under_blanc();
  847.     }
  848. }
  849.  
  850. void
  851. meta_l()
  852. {
  853.     meta_lu(etc_tolower);
  854. }
  855.  
  856. void
  857. meta_u()
  858. {
  859.     meta_lu(etc_toupper);
  860. }
  861.  
  862. void
  863. meta_lu(UINT (*func)())
  864. {
  865.     UNIT *lp;
  866.     int lbp;
  867.  
  868.     lp = CL;
  869.     lbp = ANALYZE[CPX].BPOS;
  870.     meta_f_alpha_end();
  871.     ctrl_x_ctrl_lu_sub(lp,lbp,CL,ANALYZE[CPX].BPOS,func);
  872. }
  873.  
  874. void
  875. meta_v()
  876. {
  877.     ctrl_z();
  878. }
  879.  
  880. /* すべてのファイルをセーブしてから終了 */
  881. void
  882. meta_z()
  883. {
  884.     register int t;
  885.  
  886.     for(t=0;t<MAX_TEXT;t++) {
  887.         if ((TDATA[t].TEXT_FILE != -1) && (1)) {    /* 次のが見つかった */
  888.             window_set_text(CWN,t);
  889.             window_set_current(CWN);
  890.             if (*FILE_NAMES_ST[WDATA[CWN].WTEXTS].CONTENT != '[') {
  891.                 ctrl_x_ctrl_s();
  892.             }
  893.         }
  894.     }
  895.     ctrl_x_ctrl_c();
  896. }
  897.  
  898. void
  899. meta_gyo()
  900. {
  901.     meta_ctrl_l();
  902. }
  903.  
  904. /* 最初の1文字だけ大文字に */
  905. void
  906. meta_c()
  907. {
  908.     UNIT *lp;
  909.     int lbp;
  910.  
  911.     lp = CL;
  912.     lbp = ANALYZE[CPX].BPOS;
  913.     meta_f_alpha_end();
  914.     meta_c_sub(lp,lbp,CL,ANALYZE[CPX].BPOS);
  915. }
  916.  
  917. void
  918. meta_c_sub(UNIT *lp,int lbp,UNIT *rp,int rbp)
  919. {
  920.     UNIT *wp;
  921.     register int wb,nb;
  922.     int x0=0;
  923.     UBYTE w[VERY_LONG_LINE*4];
  924.     register STR pp;
  925.     register UINT c,c0;
  926.     register int flag;
  927.  
  928. /*    etc_line_order(&lp,&lbp,&rp,&rbp);*/
  929.     line_get_body(w,wp = lp);
  930.     wb = lbp;
  931.     flag = 0;
  932.     while((wp != rp) || (wb < rbp)) {
  933.         pp =line_skip_xcode(&w[wb]);
  934.         if (c0 = (*pp)) {    /* 行末ではない */
  935.             if (flag) {    /* 既に先頭を処理した */
  936.                 if (iskanji(c0)) {
  937.                     c0 = (c0 << 8) | (UBYTE)pp[1];
  938.                     c = etc_tolower(c0);
  939.                     if (c != c0) {
  940.                         *pp = (c >> 8) & 0xff;
  941.                         pp[1] = c & 0xff;
  942.                         flag = 1;
  943.                     }
  944.                 } else {
  945.                     c = etc_tolower(c0);
  946.                     if (c != c0) {
  947.                         *pp = c;
  948.                         flag = 1;
  949.                     }
  950.                 }
  951.             } else {
  952.                 if (iskanji(c0)) {
  953.                     c0 = (c0 << 8) | (UBYTE)pp[1];
  954.                     c = etc_toupper(c0);
  955.                     if (c != c0) {
  956.                         *pp = (c >> 8) & 0xff;
  957.                         pp[1] = c & 0xff;
  958.                         flag = 1;
  959.                     }
  960.                 } else {
  961.                     c = etc_toupper(c0);
  962.                     if (c != c0) {
  963.                         *pp = c;
  964.                         flag = 1;
  965.                     }
  966.                 }
  967.                 if (!flag && (etc_tolower(c0) != c0)) {    /* low にできるコードである */
  968.                     flag = 2;
  969.                 }
  970.             }
  971.         }
  972.         nb = line_touch_next_char_x(w,wb,&x0);
  973.         if (nb == wb) {
  974.             line_store_and_echo(wp,w);    /* 納める */
  975.             line_get_body(w,wp = wp->ATO);    /* 次の行へ */
  976.             flag = wb = 0;    /* 行頭から */
  977.         } else {
  978.             wb = nb;    /* 次の文字へ */
  979.         }
  980.     }
  981.     if (flag == 1) {
  982.         line_store_and_echo(wp,w);    /* 納める */
  983.         change_check();
  984.     }
  985.     line_cl_cl();
  986.     work_line_analyze();
  987. }
  988.  
  989. void
  990. meta_replace_r(int go_flag)
  991. {
  992.     UBYTE w[VERY_LONG_LINE * 4];
  993.     UNIT *pp0,*pp,*p1,*p2;
  994.     UNIT *lp1,*lp2;
  995.     int bb0,bb,b1,b2;
  996.     int count = 0;
  997.     UINT c;
  998.     int xflag,flag,uflag;
  999.     int give_up;
  1000.     
  1001.     lp1 = NULL;    /* 初期化 */
  1002. /* go_flag = 確認せずに置換を強行 */
  1003. /* xflag = 置換を続行 */
  1004. /* flag = 次の置換に行ってはいけない */
  1005.  
  1006.     etc_string_esc_cnv(STRING_ESC1,STRING_ESC1_s);
  1007.     if (go_flag) {
  1008.         sprintf((char *) w,"逆方向置換 [%s]<META>",STRING_ESC1_s);
  1009.     } else {
  1010.         sprintf((char *) w,"逆方向確認置換 [%s]<META>",STRING_ESC1_s);
  1011.     }
  1012.     if (under_input_esc(w,STRING_ESC1) < 0) {    /* 無効であった = ^G */
  1013.         under_print((STR)"[中断]");
  1014.         return;
  1015.     }
  1016.     if (!*STRING_ESC1) {    /* 置換元が無い */
  1017.         under_blanc();
  1018.         return;
  1019.     }
  1020.     etc_string_esc_cnv(STRING_ESC1,STRING_ESC1_s);
  1021.  
  1022.     etc_string_esc_cnv(STRING_ESC2,STRING_ESC2_s);
  1023.     sprintf((char *) w,"with [%s]<META>",STRING_ESC2_s);
  1024.     if (under_input_esc(w,STRING_ESC2) < 0) {    /* 無効であった = ^G */
  1025.         under_print((STR)"[中断]");
  1026.         return;
  1027.     }
  1028.     etc_string_esc_cnv(STRING_ESC2,STRING_ESC2_s);
  1029.     /* 確認置換実行 */
  1030.     line_seigyou();    /* 整行する */
  1031.     pp0 = pp = CL;
  1032.     bb0 = bb = ANALYZE[CPX].BPOS;
  1033.     xflag = 1;
  1034.     uflag = 0;
  1035.     strcpy(STRING_ESC1_u,STRING_ESC1);
  1036.     etc_jstrup(STRING_ESC1_u);
  1037.     while(xflag) {
  1038.         if (!uflag) {
  1039.             give_up = ctrl_r_get_string(pp,bb,STRING_ESC1_u,&p1,&b1,&p2,&b2);
  1040.             if (!give_up) {
  1041.                 break;
  1042.             }
  1043.         } else {    /* ??? */
  1044.             uflag = 0;
  1045.             give_up = ctrl_r_get_string(pp,bb,STRING_ESC1_u,&p1,&b1,&p2,&b2);
  1046.             if (!give_up) {
  1047.                 break;
  1048.             }
  1049.         }
  1050.         if (give_up < 0) {
  1051.             goto replace_give_up;
  1052.         }
  1053.         jump(p1,b1);
  1054. /* 置換元に属性が前置している可能性がある */
  1055.         b1 = line_remove_attribute(b1);
  1056. /* 前置している属性までさかのぼる */
  1057.         if (!go_flag) {    /* 確認モードである */
  1058.             sprintf((char *)w,"置換 '%s' with '%s'?",STRING_ESC1_s,STRING_ESC2_s);
  1059.             under_print(w);
  1060.         }
  1061.         if (CPX && (line_cl_1byte(CPX-1) == CR)) {
  1062.                 /* 左が改行 */
  1063.             if (CL->ATO == TAIL) {
  1064.                 ctrl_b();
  1065.             } else {
  1066.                 ctrl_f();
  1067.             }
  1068.         }
  1069.         work_cursor_cpx();
  1070.         flag = 1;
  1071.         while(flag) {
  1072.             int lb1,lb2;
  1073.  
  1074.             if (go_flag) {
  1075.                 c = 'Y';    /* ううう、CL は最後にいじるだけにすべき! */
  1076.             } else {
  1077.                 c = toupper(fep_inkey_raw());
  1078.             }
  1079.             switch(c) {
  1080.             case '!':    /* 最後まで強行 */
  1081.                 go_flag = 1;
  1082.             case 'Y':
  1083.             case ' ':
  1084.                 line_seigyou();
  1085.                 work_replace_str_echo_xxx(p1,b1,p2,b2,STRING_ESC2);
  1086.                 lp1 = p1;
  1087.                 lb1 = b1;
  1088.                 line_seigyou();
  1089.                     /* BAG が発生する可能性有り */
  1090.                 ctrl_r_trace_real_byte(p1,b1,strlen(STRING_ESC2),&pp,&bb);
  1091. /*printf("[%x:%d,%x:%d]",p1,b1,pp,bb);binkey();*/
  1092.                 lp2 = pp;
  1093.                 lb2 = bb;
  1094.                 count++;
  1095.                 flag = 0;
  1096.                 change_check();
  1097.                 break;
  1098.  
  1099.             case 'N':
  1100.                 pp = p2;
  1101.                 bb = b2;
  1102.                 flag = 0;
  1103.                 break;
  1104.             case 'U':    /* 1個だけチャイして続行 */
  1105.                 if (lp1) {
  1106.                     work_replace_str_echo_xxx(lp1,lb1,lp2,lb2,STRING_ESC1);
  1107.                     line_seigyou();
  1108.                         /* BAG が発生する可能性有り */
  1109.                     count--;
  1110.                     change_check();
  1111.                     pp = lp1;
  1112.                     bb = lb1;
  1113.                     lp1 = NULL;
  1114.                     flag = 0;
  1115.                     uflag = 1;
  1116.                 } else {
  1117.                     etc_beep();
  1118.                     work_cursor_cpx();
  1119.                 }
  1120.                 break;
  1121.             case '.':
  1122.                 pp = pp0;
  1123.                 bb = bb0;
  1124.                 flag = 0;
  1125.                 xflag = 0;
  1126. /*                jump(pp0,bb0);*/
  1127.             case 'G'-'@':    /* その場で中断 */
  1128. replace_give_up:
  1129.                 flag = 0;
  1130.                 xflag = 0;
  1131.                 pp = CL;
  1132.                 bb = ANALYZE[CPX].BPOS;
  1133.                 break;
  1134.             default:    /* beep 音を出してヘルプ */
  1135.                 etc_beep();
  1136.             case '?':    /* ヘルプ */
  1137. under_print((STR)"(Y or SPACE)置換 (N)無視 (!)強行 (U)キャンセル (^G)中断 (.)戻る (?)ヘルプ:");
  1138.                 continue;
  1139.             }
  1140.         }
  1141.     }
  1142.     jump(pp,bb);
  1143.     if (CPX && (line_cl_1byte(CPX-1) == CR)) {
  1144.             /* 左が改行 */
  1145.         ctrl_b();
  1146.     }
  1147.     sprintf((char *)w,"%d 箇所 置換しました",count);
  1148.     under_print(w);
  1149. }
  1150.  
  1151.